package com.soriya.nestlive.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import com.soriya.nestlive.db.dao.ChannelInfoDao
import com.soriya.nestlive.model.ResponseResult
import com.soriya.nestlive.model.Video
import com.soriya.nestlive.model.form.PublishVideoForm
import com.soriya.nestlive.repository.VideoByCategoryPagingRepository
import com.soriya.nestlive.repository.VideoByChannelPagingRepository
import com.soriya.nestlive.repository.VideoRepository
import com.soriya.nestlive.repository.VideoSearchPagingRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import javax.inject.Inject

@HiltViewModel
class VideoModel @Inject constructor(
    private val videoRepository: VideoRepository,
    private val videoByChannelPagingRepository: VideoByChannelPagingRepository,
    private val videoByCategoryPagingRepository: VideoByCategoryPagingRepository,
    private val videoSearchPagingRepository: VideoSearchPagingRepository,
    private val channelInfoDao: ChannelInfoDao
) : ViewModel() {

    private val _videoDetail: MutableStateFlow<Video?> = MutableStateFlow(null)

    val videoDetail: StateFlow<Video?> = _videoDetail

    fun getVideoListByChannelId(channelId: Long) = Pager(
        PagingConfig(
            pageSize = 5, // 页面大小
            prefetchDistance = 2, // 距离底部还有多少条数据加载下一页
            enablePlaceholders = false, // 控件占位 false不占位
            initialLoadSize = 5 // 初始化时加载多少条数据
        )
    ) {
        videoByChannelPagingRepository.channelId = channelId
        videoByChannelPagingRepository
    }.flow

    fun getVideoListByCategoryId(categoryId: Long) = Pager(
        PagingConfig(
            pageSize = 5, // 页面大小
            prefetchDistance = 2, // 距离底部还有多少条数据加载下一页
            enablePlaceholders = false, // 控件占位 false不占位
            initialLoadSize = 5 // 初始化时加载多少条数据
        )
    ) {
        videoByCategoryPagingRepository.categoryId = categoryId
        videoByCategoryPagingRepository
    }.flow

    fun search(key: String) = Pager(
        PagingConfig(
            pageSize = 5, // 页面大小
            prefetchDistance = 2, // 距离底部还有多少条数据加载下一页
            enablePlaceholders = false, // 控件占位 false不占位
            initialLoadSize = 5 // 初始化时加载多少条数据
        )
    ) {
        videoSearchPagingRepository.key = key
        videoSearchPagingRepository
    }.flow

    fun getDetailById(videoId: Long) {
        viewModelScope.launch {
            videoRepository.getById(videoId).collect { res ->
                when (res) {
                    is ResponseResult.Success<*> -> {
                        if (res.code == 200) {
                            _videoDetail.emit(res.data as Video)
                        }
                    }
                    is ResponseResult.Failed -> {}
                    is ResponseResult.Loading -> {}
                }
            }
        }
    }

    fun publishVideo(publishVideoForm: PublishVideoForm): Flow<Unit?> = flow {
        channelInfoDao.selectOne().collect { channelInfo ->
            channelInfo?.let {
                val cover = publishVideoForm.cover
                val source = publishVideoForm.source

                val coverRequest = cover.toRequestBody("multipart/form-data".toMediaTypeOrNull())
                val sourceRequest = source.asRequestBody("multipart/form-data".toMediaTypeOrNull())

                val multipartBody = MultipartBody.Builder()
                    .addFormDataPart("source", source.name, sourceRequest)
                    .addFormDataPart("cover", "cover.jpg", coverRequest)
                    .addFormDataPart("channelId", it.channelId.toString())
                    .addFormDataPart("categoryId", publishVideoForm.categoryId.toString())
                    .addFormDataPart("videoName", publishVideoForm.videoName)
                    .addFormDataPart("videoDesc", publishVideoForm.videoDesc)
                    .addFormDataPart("duration", publishVideoForm.duration.toString())
                    .build()

                videoRepository.publishVideo(multipartBody).collect { res ->
                    when (res) {
                        is ResponseResult.Success<*> -> {
                            if (res.code == 200) {
                                emit(Unit)
                            }
                        }
                        is ResponseResult.Failed -> {}
                        is ResponseResult.Loading -> {}
                    }
                }
            }
        }
    }

}